<?php

namespace App\Http\Controllers;

use App\Exceptions\ApiException;
use App\Exceptions\R;
use App\Helpers\excel\ChunkReadFilter;
use App\Helpers\excel\MyReadFilter;
use App\Models\ProductNameModel;
use App\Models\ProductsBatchModel;
use App\Models\ProductsSaleModel;
use App\Models\ReportModel;
use App\Models\SearchDataModel;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Reader\Csv;
use function app\Helpers\sys;

class HomeController extends Controller
{
    public function export()
    {
        $inputFileType = 'Csv';
        $inputFileName = 'C:\Users\wcx\Desktop\excel\相关分析.csv';
        /**  Create a new Reader of the type defined in $inputFileType  **/
        /** @var Csv $reader */
        $reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
        $reader->setReadDataOnly(true);
        $readFilter = new MyReadFilter(2, 600, array_merge(['A'], range('C', 'P')));
        $reader->setReadFilter($readFilter);
        //        $reader->setInputEncoding('UTF-8');
        $reader->setDelimiter("\t");
        $spreadsheet = $reader->load($inputFileName);
        $data        = $spreadsheet->getActiveSheet()->toArray(null, true, true, true);
        $data        = array_column($data, 'A');
        $column      = [
            'keyword',
            'search_people',
            'search_times',
            'click_rate',
            'click_people',
            'click_times',
            'pay_price',
            'pay_rate',
            'online_goods',
            'shop_click_rate',
            'refer_price',
            'pay_people',
            'unit_price',
            'people_div_goods',
            'price_div_goods',
        ];
        $insert      = [];
        $data        = array_filter($data);
        foreach ($data as $item) {
            $item = str_replace("\"", '', $item);
            $item = str_replace("%", '', $item);
            $item = explode(',', $item);
            unset($item[1]);
            $insert[] = array_combine($column, $item);
        }
        DB::table('search_data')->insert($insert);
//        $model = new SearchDataModel;
//        $res =SearchDataModel::create($insert[0]);
        dump("s");
        exit;
        
        /**  Define how many rows we want to read for each "chunk"  **/
        //        $chunkSize = 2048;
        //        /**  Create a new Instance of our Read Filter  **/
        //        $chunkFilter = new ChunkReadFilter();
        //
        //        /**  Tell the Reader that we want to use the Read Filter  **/
        //        $reader->setReadFilter($chunkFilter);
        //
        //        /**  Loop to read our worksheet in "chunk size" blocks  **/
        //        for ($startRow = 2; $startRow <= 65536; $startRow += $chunkSize) {
        //            /**  Tell the Read Filter which rows we want this iteration  **/
        //            $chunkFilter->setRows($startRow, $chunkSize);
        //            /**  Load only the rows that match our filter  **/
        //            $spreadsheet = $reader->load($inputFileName);
        //            dump($spreadsheet->getActiveSheet()->toArray(null, true, true, true));exit;
        //            //    Do some processing here
        //        }
        dump("d");
        exit;
    }
    
    public function combine()
    {
        $inputFileType  = 'Csv';
        $inputFileNames = [
            'C:\Users\wcx\Desktop\相关分析.csv',
            'C:\Users\wcx\Desktop\相关分析 2.csv',
        ];
        /** @var Csv $reader */
        $reader        = IOFactory::createReader($inputFileType);
        $inputFileName = array_shift($inputFileNames);
        dump('Loading file ' . pathinfo($inputFileName, PATHINFO_BASENAME) . ' into WorkSheet #1 using IOFactory with a defined reader type of ' . $inputFileType);
        $spreadsheet = $reader->load($inputFileName);
        $spreadsheet->getActiveSheet()->setTitle(pathinfo($inputFileName, PATHINFO_BASENAME));
        foreach ($inputFileNames as $sheet => $inputFileName) {
            dump('Loading file ' . pathinfo($inputFileName, PATHINFO_BASENAME) . ' into WorkSheet #' . ($sheet + 2) . ' using IOFactory with a defined reader type of ' . $inputFileType);
            $reader->setSheetIndex($sheet + 1);
            $reader->loadIntoExisting($inputFileName, $spreadsheet);
            $spreadsheet->getActiveSheet()->setTitle(pathinfo($inputFileName, PATHINFO_BASENAME));
        }
        
        dump($spreadsheet->getSheetCount() . ' worksheet' . (($spreadsheet->getSheetCount() == 1) ? '' : 's') . ' loaded');
        $loadedSheetNames = $spreadsheet->getSheetNames();
        foreach ($loadedSheetNames as $sheetIndex => $loadedSheetName) {
            dump('<b>Worksheet #' . $sheetIndex . ' -> ' . $loadedSheetName . '</b>');
            $spreadsheet->setActiveSheetIndexByName($loadedSheetName);
            $sheetData = $spreadsheet->getActiveSheet()->toArray(null, true, true, true);
            var_dump($sheetData);
        }
        dump("Sd");
        exit;
        
        /**  Create a new Reader of the type defined in $inputFileType  **/
        $reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
        
        /**  Extract the first named file from the array list  **/
        $inputFileName = array_shift($inputFileNames);
        /**  Load the initial file to the first worksheet in a `Spreadsheet` Object  **/
        $spreadsheet = $reader->load($inputFileName);
        /**  Set the worksheet title (to the filename that we've loaded)  **/
        $spreadsheet->getActiveSheet()
            ->setTitle(pathinfo($inputFileName, PATHINFO_BASENAME));
        
        /**  Loop through all the remaining files in the list  **/
        foreach ($inputFileNames as $sheet => $inputFileName) {
            /**  Increment the worksheet index pointer for the Reader  **/
            $reader->setSheetIndex($sheet + 1);
            /**  Load the current file into a new worksheet in Spreadsheet  **/
            $reader->loadIntoExisting($inputFileName, $spreadsheet);
            /**  Set the worksheet title (to the filename that we've loaded)  **/
            $spreadsheet->getActiveSheet()
                ->setTitle(pathinfo($inputFileName, PATHINFO_BASENAME));
        }
    }
    
    public function test()
    {
        $url       = "http://www.zs.qsst.moa.gov.cn/sofn-tts-web-branch/ttsScltxxcjProduct/getProductPageInfo?=146988523b6d418c8c6bc5630f1256aa1cfca45c52ff4cbf9b162c05246cb09e";
        $post_data = [
            'industry' => "04",
            'id'       => '146988523b6d418c8c6bc5630f1256aa1cfca45c52ff4cbf9b162c05246cb09e',
            'length'   => 1600,
            'start'    => 1,
        ];
        $header    = [
            'token:eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiYWRtaW4iLCJhY2NvdW50IjoianlrYzg4ODg4IiwidXNlcklkIjoiNzU4OWFjNmUxZWIyNGI2MTk5OTY1ZWRlY2JhZDQ3Y2FmM2JiNWUwN2Y0NGE0MDMwYjA4NDNhYjdmYjJhOWFiMCIsImlzcyI6InJlc3RhcGl1c2VyIiwiYXVkIjoiMDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjYyN2I0ZjYiLCJleHAiOjE1ODgxNjYwMjYsIm5iZiI6MTU4Nzk5MzIyNn0.1B7QQkWInGyDFQcLnq6vep7xkAX-3GPC5WYnh8jflf8',
        ];
        $res       = $this->postUrl($url, $post_data, $header);
        $all       = json_decode($res, true)['data']['list'];
        foreach ($all as $v) {
            $data = [
                'industry'            => 4,
                'name'                => $v['name'],
                'en_name'             => $v['enname'] ?? '',
                'desc'                => $v['description'] ?? '',
                'gb_code'             => $v['gbCode'] ?? '',
                'product_code'        => $v['productCode'],
                'parent_product_code' => $v['parentId'],
                'variety_name'        => $v['parentName'],
                'level'               => mb_strlen($v['productCode']),
            ];
            ProductNameModel::create($data);
        }
        print_r("d");
        exit;
    }
    
    public function cal_sum($str)
    {
        $len = strlen($str);
        $sum = 0;
        for ($i = 0; $i < $len; $i++) {
            $sum += intval(substr($str, $i, 1));
        }
        return $sum;
    }
    
    public function postUrl($url, $postData = false, $header = false)
    {
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //返回数据不直接输出
        curl_setopt($ch, CURLOPT_ENCODING, "gzip"); //指定gzip压缩
        //add header
        if (!empty($header)) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        }
        //add ssl support
        if (substr($url, 0, 5) == 'https') {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);    //SSL 报错时使用
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);    //SSL 报错时使用
        }
        //add 302 support
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        //        curl_setopt($ch, CURLOPT_COOKIEFILE, $this->lastCookieFile); //使用提交后得到的cookie数据
        //add post data support
        if (!empty($postData)) {
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
        }
        try {
            $content = curl_exec($ch); //执行并存储结果
        } catch (\Exception $e) {
            $this->_log($e->getMessage());
        }
        $curlError = curl_error($ch);
        if (!empty($curlError)) {
            $this->_log($curlError);
        }
        curl_close($ch);
        return $content;
    }
    
    /**
     * 获取溯源码结果
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse|object
     * @throws ApiException
     * @throws \Psr\SimpleCache\InvalidArgumentException
     */
    public function apiScanResult(Request $request)
    {
        $params = $request->all();
        $this->validateRequest($params, [
            'source_code' => 'required',
        ]);
        $scan_times = 0;//扫码次数
        $scan_model = null;//扫码对象
        $customer   = null;//客户
        //查找销售记录
        $saleHistory = ProductsSaleModel::withTrashed()->where('code', $params['source_code'])
            ->select('sale_id', 'batch_id', 'customer_id', 'sale_num', 'sale_type', 'scan_times')
            ->first();
        $with        = ['base:base_id,name,address_text,address,master_name,phone,longitude,latitude'];
        $fields      = ['scan_times', 'auth_type', 'batch_id', 'product_id', 'unit', 'number', 'quality_result', 'quality_type', 'source', 'source_code', 'image', 'video', 'receive_time', 'base_id', 'quality_image'];
        
        if ($saleHistory) {
            $productBatch = ProductsBatchModel::withTrashed()->where('batch_id', $saleHistory['batch_id'])
                ->with($with)
                ->select($fields)
                ->first();
            $scan_model   = clone $saleHistory;
            $scan_times   = $saleHistory['scan_times'];
        } else {//查找产品批次
            $productBatch = ProductsBatchModel::withTrashed()->where('source_code', $params['source_code'])
                ->with($with)
                ->select($fields)
                ->first();
            if (!$productBatch) {//销售记录和产品批次都没有
                throw new ApiException(R::ERROR, '溯源码不存在');
            }
            $scan_model  = clone $productBatch;
            $scan_times  = $productBatch['scan_times'];
            $saleHistory = ProductsSaleModel::withTrashed()->where('batch_id', $productBatch['batch_id'])
                ->select('sale_id', 'batch_id', 'customer_id', 'sale_num', 'sale_type')
                ->first();
        }
        $customer             = $productBatch['Customer'] ?: $saleHistory['Customer'];
        $productBatch['unit'] = ProductsBatchModel::MAP_UNIT[$productBatch['unit']];
        
        $str = '';
        $arr = explode(',', $productBatch['auth_type']);
        foreach ($arr as $k => $v) {
            if ($k > 0) {
                $str .= ',' . ProductsBatchModel::MAP_AUTH[$v];
            } else {
                $str .= ProductsBatchModel::MAP_AUTH[$v];
            }
        }
        
        $productBatch['auth_str'] = $str;
        $product                  = $productBatch['product'];
        $source_code              = $params['source_code'];
        //是否已扫过
        $key = "{$source_code}:scan:" . date("Ymd");
        //        Cache::store('file')->delete($key);
        //        dump("d");exit;
        if (!Cache::store('file')->has($key)) {
            Cache::store('file')->set($key, [], 86400);
        }
        $scanned = Cache::store('file')->get($key);
        if (!$scanned || !in_array($_SERVER['REMOTE_ADDR'], $scanned)) {
            $scanned[] = $_SERVER['REMOTE_ADDR'];
            Cache::store('file')->set($key, $scanned, 86400);
            //扫描次数+1
            $scan_model['scan_times'] = $scan_model['scan_times'] + 1;
            $scan_model->save();
            $scan_times += 1;
        }
        return R::Api(compact('productBatch', 'product', 'saleHistory', 'customer', 'source_code', 'scan_times'), R::SUCCESS, '获取成功');
    }
    
    /**
     * 获取溯源码结果
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse|object
     * @throws ApiException
     */
    public function scanResult(Request $request)
    {
        $params = $request->all();
        $this->validateRequest($params, [
            'source_code' => 'required',
        ]);
        $source_code = $params['source_code'];
        
        //查找销售记录
        $saleHistory = ProductsSaleModel::withTrashed()->where('code', $params['source_code'])
            ->select('sale_id', 'batch_id', 'customer_id', 'sale_num', 'sale_type', 'scan_times')
            ->first();
        $with        = ['base:base_id,longitude,latitude'];
        $fields      = ['batch_id', 'product_id', 'base_id'];
        
        if ($saleHistory) {
            $productBatch = ProductsBatchModel::withTrashed()->where('batch_id', $saleHistory['batch_id'])
                ->with($with)
                ->select($fields)
                ->first();
        } else {//查找产品批次
            $productBatch = ProductsBatchModel::withTrashed()->where('source_code', $params['source_code'])
                ->with($with)
                ->select($fields)
                ->first();
        }
        $longitude = $productBatch['base']['longitude'] ?? 0;
        $latitude  = $productBatch['base']['latitude'] ?? 0;
        return view('home.result', compact('source_code', 'longitude', 'latitude'));
    }
    
    /**
     * 举报
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse|object
     * @throws ApiException
     */
    public function report(Request $request)
    {
        $params = $request->all();
        $this->validateRequest($params, [
            'source_code' => 'required',
            'name'        => '',
            'phone'       => 'required|digits:11',
            'reason'      => 'required',
            'batch_id'    => 'required|integer|gt:0',
        ], [], [
                                   'source_code' => '溯源码',
                                   'phone'       => '手机号',
                                   'name'        => '名字',
                                   'reason'      => '举报理由',
                                   'batch_id'    => '批次号',
                               ]);
        $had_reported = ReportModel::where('phone', $params['phone'])->where('code', $params['source_code'])->first();
        if ($had_reported) {
            throw new ApiException(R::ERROR, '您已举报过该产品,不可重复举报');
        }
        $report             = new ReportModel();
        $report['batch_id'] = $params['batch_id'];
        $report['reason']   = $params['reason'];
        $report['code']     = $params['source_code'];
        $report['phone']    = $params['phone'];
        $report['ip']       = $request->ip();
        
        $report->save();
        return R::Api([], R::SUCCESS, '举报成功');
    }
}
